home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / init.c < prev    next >
C/C++ Source or Header  |  1979-12-31  |  17KB  |  817 lines

  1. /* --------------------------------- init.c --------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* startup code.
  8. */
  9.  
  10. #include "fly.h"
  11.  
  12.  
  13. LOCAL_FUNC int NEAR
  14. get_option (char *e)
  15. {
  16.     char    t, *p;
  17.     int    errs = 0, itemp;
  18.     long    ltemp;
  19.  
  20.     while (e[0] == ' ')
  21.         ++e;
  22.     if (e[0] == '\0')
  23.         return (0);
  24.  
  25. /* Find first space and replace it with a string terminator.
  26. */
  27.     for (t = 0, p = e; *p; ++p) {
  28.         if (isspace (*p)) {
  29.             t = *p;
  30.             *p = '\0';
  31.             break;
  32.         }
  33.     }
  34.  
  35.     LogPrintf (" %s\n", e);
  36.     switch (e[0]) {
  37.     case 'b':
  38.         if (e[1] >= '0' && e[1] <= '9')
  39.             st.windows = (int)(e[1] - '0');
  40.         else if ('e' == e[1])
  41.             st.windows = WIN_ETHER;
  42.         else
  43.             st.windows = WIN_FULL;
  44.         break;
  45.     case 'c':
  46.         if (get_long (e+2, <emp) ||
  47.             set_rrggbb (e[1], (Ulong)ltemp)) {
  48.             LogPrintf ("bad color %s\n", e);
  49.             ++errs;
  50.         }
  51.         break;
  52.     case 'd':            /* devices */
  53.         switch (e[1]) {
  54.         case 'k':        /* keyboard */
  55.             st.kbdname = STRfree (st.kbdname);
  56.             st.kbdname = STRdup (e+2);
  57.             break;
  58.         case 'n':        /* netport */
  59.             {
  60.                 struct netname    *p;
  61.  
  62.                 if (!NEW (p)) {
  63.                     LogPrintf ("no mem for netname\n");
  64.                     ++errs;
  65.                     break;
  66.                 }
  67.                 p->name = STRdup (e+2);
  68.                 p->next = st.netnames;
  69.                 st.netnames = p;
  70.             }
  71.             break;
  72.         case 'p':        /* pointer */
  73.             st.ptrname = STRfree (st.ptrname);
  74.             st.ptrname = STRdup (e+2);
  75.             break;
  76.         case 's':        /* sound */
  77.             st.sndname = STRfree (st.sndname);
  78.             st.sndname = STRdup (e+2);
  79.             break;
  80.         case 't':        /* timer */
  81.             st.timeropts = STRfree (st.timeropts);
  82.             st.timeropts = STRdup (e+2);
  83.             break;
  84.         case 'v':        /* video */
  85.             st.grname = STRfree (st.grname);
  86.             st.grname = STRdup (e+2);
  87.             break;
  88.         default:
  89.             goto too_bad;
  90.         }
  91.         break;
  92.     case 'D':
  93.         st.dtype = STRfree (st.dtype);
  94.         st.dtype = STRdup (e+1);
  95.         break;
  96.     case 'f':
  97.         st.fname = STRfree (st.fname);
  98.         st.fname = STRdup (e+1);
  99.         break;
  100.     case 'F':
  101.         /* already processed */
  102.         break;
  103.     case 'h':
  104.     case '?':
  105. help:
  106.         welcome (2);
  107. #ifdef NOSTDERR
  108. #define SHOW(x)    LogPrintf (x)
  109. #else
  110. #define SHOW(x)    fprintf (stderr, x)
  111. #endif
  112.         SHOW ("usage: fly8 [options]\n");
  113.         SHOW ("       see ini.doc for options\n");
  114. #undef SHOW
  115.         ++errs;
  116.         break;
  117.     case 'H':
  118.         st.homename = STRfree (st.homename);
  119.         st.homename = STRdup (e+1);
  120.         break;
  121.     case 'i':
  122.         st.initkeys = STRfree (st.initkeys);
  123.         st.initkeys = STRdup (e+1);
  124.         break;
  125.     case 'I':
  126.         /* already processed */
  127.         break;
  128.     case 'L':
  129.         /* already processed */
  130.         break;
  131.     case 'm':
  132.         st.grmname = STRfree (st.grmname);
  133.         st.grmname = STRdup (e+1);
  134.         break;
  135.     case 'M':
  136.         st.mname = STRfree (st.mname);
  137.         st.mname = STRdup (e+1);
  138.         break;
  139.     case 'n':
  140.         if (get_long (e+2, <emp)) {
  141. bad_num:
  142.             LogPrintf ("bad number in '%s'\n", e);
  143.             ++errs;
  144.             break;
  145.         }
  146.         switch (e[1]) {
  147.         case 'b':        /* max num of display list lines */
  148.             itemp = (int)(ltemp/BUFLEN*2+1);
  149.             if (itemp < 20)
  150.                 goto bad_num;
  151.             st.maxbuffers = (Ushort)itemp;
  152.             break;
  153.         case 'i':        /* plane dynamics minimal interval */
  154.             if (ltemp < 1)
  155.                 goto bad_num;
  156.             st.misc[6] = (int)ltemp;
  157.             break;
  158.         case 'l':        /* log flush rate */
  159.             if (ltemp < 0 || ltemp > 30000)
  160.                 goto bad_num;
  161.             st.misc[9] = (int)ltemp;
  162.             break;
  163.         case 'm':        /* num of macros */
  164.             if (ltemp < 1)
  165.                 goto bad_num;
  166.             st.nMacros = (Ushort)ltemp;
  167.             break;
  168.         case 'r':        /* history recall queue size */
  169.             if (ltemp < 1)
  170.                 goto bad_num;
  171.             st.maxrecall = (Ushort)ltemp;
  172.             break;
  173.         case 't':        /* num of secs till shutdown */
  174.             if (ltemp < 0)
  175.                 goto bad_num;
  176.             st.ShutdownTime = ltemp*1000L;
  177.             break;
  178.         default:
  179.             goto too_bad;
  180.             break;
  181.         }
  182.         break;
  183.     case 'N':
  184.         st.nikname = STRfree (st.nikname);
  185.         if (e[1]) {
  186.             st.nikname = STRdup (e+1);
  187.             if (strlen (st.nikname) >LNAME-1)   /* keep it short */
  188.                 st.nikname[LNAME-1] = '\0';
  189.         }
  190.         break;
  191.     case 'o':
  192.         SetOption (0, itemp = 1);
  193.         for (p = e + 1; *p; ++p) {
  194.             switch (*p) {
  195.             case '-':
  196.                 SetOption (0, itemp = 0);
  197.                 break;
  198.             case '+':
  199.                 SetOption (0, itemp = 1);
  200.                 break;
  201.             case '^':
  202.                 SetOption (0, itemp = 2);
  203.                 break;
  204.             case 'l':
  205.                 SetOption (&st.flags, SF_LANDSCAPE);
  206.                 break;
  207.             case 'q':
  208.                 if (0 == itemp)
  209.                     st.quiet = 1;    /* quiet off */
  210.                 else if (1 == itemp)
  211.                     st.quiet = 0;    /* quiet on */
  212.                 else
  213.                     st.quiet = (st.quiet + 1) % 3;
  214.                 break;
  215.             case 'v':
  216.                 SetOption (&st.flags, SF_VERBOSE);
  217.                 break;
  218.             default:
  219.                 goto too_bad;
  220.             }
  221.         }
  222.         break;
  223.     case 'P':
  224.         st.ptype = STRfree (st.ptype);
  225.         st.ptype = STRdup (e+1);
  226.         break;
  227.     case 'r':
  228.         itemp = 1;
  229.         if (e[itemp] == '0') {
  230.             st.network &= ~NET_ON;
  231.             ++itemp;
  232.         } else
  233.             st.network |= NET_ON;
  234.         if (e[itemp] == 'l') {
  235.             ++itemp;
  236.             if (e[itemp] == '0') {
  237.                 st.network &= ~NET_NOBCAST;
  238.                 ++itemp;
  239.             } else
  240.                 st.network |= NET_NOBCAST;
  241.         }
  242.         break;
  243.     case 'T':
  244.         st.teamname = STRfree (st.teamname);
  245.         if (e[1]) {
  246.             st.teamname = STRdup (e+1);
  247.             if (strlen (st.teamname) >LNAME-1)  /* keep it short */
  248.                 st.teamname[LNAME-1] = '\0';
  249.         }
  250.         break;
  251.     case 'V':
  252.         if ('\0' == e[1]) {
  253.             ++errs;
  254.             goto help;
  255.         }
  256.         st.vmdname = STRfree (st.vmdname);
  257.         st.vmdname = STRdup (e+1);
  258.         break;
  259.     case 'X':
  260.         st.navname = STRfree (st.navname);
  261.         st.navname = STRdup (e+1);
  262.         break;
  263.     case 'Y':
  264.         st.lndname = STRfree (st.lndname);
  265.         st.lndname = STRdup (e+1);
  266.         break;
  267.     case 'z':
  268.         st.flags ^= SF_BLANKER;
  269.         if (e[1]) {
  270.             if (get_int (e+1, &itemp) ||
  271.                 itemp < 0) {
  272.                 LogPrintf ("use -znn\n");
  273.                 ++errs;
  274.             }
  275.             st.drones = itemp;
  276.         } else
  277.             st.drones = 0;
  278.         break;
  279.     default:
  280. too_bad:
  281.         LogPrintf ("unknown option %s\n", e);
  282.         ++errs;
  283.         break;
  284.     }
  285.     if (t)
  286.         *p = t;
  287.     return (errs);
  288. }
  289.  
  290. LOCAL_FUNC int NEAR
  291. get_argopts (char **a)
  292. {
  293.     int    errs = 0;
  294.     char    *p;
  295.  
  296.     if (*a)
  297.         LogPrintf ("command line args:\n");
  298.  
  299.     while (T(p = *a++)) {
  300.         p = STRdup (p+(p[0] == '-'));
  301.         errs += get_option (p);
  302.         p = STRfree (p);
  303.     }
  304.     return (errs);
  305. }
  306.  
  307. LOCAL_FUNC int NEAR
  308. get_envopts (void)
  309. {
  310.     char    *e, *p, *q;
  311.     int    errs = 0;
  312.  
  313.     e = getenv ("FLY8");
  314.     if (e) {
  315.         LogPrintf ("env args:\n");
  316.         e = STRdup (e);
  317.         for (p = e; p && *p; p = q) {
  318.             while (*p == ' ')    /* find start */
  319.                 ++p;
  320.             if (*p == '\0')
  321.                 break;
  322.             q = strchr (p, ';');    /* find end */
  323.             if (q)
  324.                 *q = '\0';    /* end string */
  325.             errs += get_option (p);
  326.             *q++ = ';';        /* restore string */
  327.         }
  328.         e = STRfree (e);
  329.     }
  330.     return (errs);
  331. }
  332.  
  333. LOCAL_FUNC FILE * NEAR
  334. find_ini (void)
  335. {
  336.     FILE    *ini;
  337.     char    *e, *p, *q;
  338.  
  339.     if (!st.iname)
  340.         st.iname = STRdup (INIFILE);
  341.  
  342.     if (T(ini = fopen (st.iname, RTMODE)))
  343.         return (ini);
  344.  
  345.     if (st.fdir) {
  346.         Sys->BuildFileName (st.filename, st.fdir, st.iname, "");
  347.         if (T(ini = fopen (st.filename, RTMODE))) {
  348.             st.iname = STRfree (st.iname);
  349.             st.iname = STRdup (st.filename);
  350.             return (ini);
  351.         }
  352.     }
  353.  
  354.     if (T(e = getenv ("HOME"))) {
  355.         Sys->BuildFileName (st.filename, e, st.iname, "");
  356.         if (T(ini = fopen (st.filename, RTMODE))) {
  357.             st.iname = STRfree (st.iname);
  358.             st.iname = STRdup (st.filename);
  359.             return (ini);
  360.         }
  361.     }
  362.  
  363.     if (T(e = getenv ("PATH"))) {
  364.         e = STRdup (e);
  365.         for (p = e; p && *p; p = q) {
  366.             q = strchr (p, PATHSEP);    /* find end */
  367.             if (q)
  368.                 *q++ = '\0';    /* end string */
  369.             Sys->BuildFileName (st.filename, p, st.iname, "");
  370.             if (T(ini = fopen (st.filename, RTMODE))) {
  371.                 st.iname = STRfree (st.iname);
  372.                 st.iname = STRdup (st.filename);
  373.                 return (ini);
  374.             }
  375.         }
  376.         e = STRfree (e);
  377.     }
  378.     return (ini);
  379. }
  380.  
  381. LOCAL_FUNC int NEAR
  382. get_iniopts (void)
  383. {
  384.     int    errs = 0, l;
  385.     FILE    *ini;
  386.     char    opt[256], *p;
  387.  
  388.     if (!(ini = find_ini ()))
  389.         return (0);
  390.  
  391.     LogPrintf ("%s args:\n", st.iname);
  392.     while (fgets (opt, sizeof (opt), ini)) {
  393.         for (p = opt; isspace (*p); ++p)
  394.             ;
  395.         if ('\n' == p[0] || '#' == p[0] || '\0' == p[0])
  396.             continue;
  397.         l = strlen(p);
  398.         p[l-1] = '\0';        /* remove '\n' */
  399.         errs += get_option (p);
  400.     }
  401.     if (ferror (ini)) {
  402.         perror ("error reading init file");
  403.         ++errs;
  404.     }
  405.  
  406.     fclose (ini);
  407.     return (errs);
  408. }
  409.  
  410. LOCAL_FUNC OBJECT * NEAR
  411. create_viewer (int type, int nzoom)
  412. {
  413.     OBJECT    *p;
  414.  
  415.     if (T(p = create_object (O_VIEWER, 1))) {
  416.         p->misc[0] = type;
  417.         save_viewport (p);
  418.         zoom (p->viewport, nzoom);
  419.     } else
  420.         MsgEPrintf (-50, "no viewer %u", type);
  421.     return (p);
  422. }
  423.  
  424. extern void FAR
  425. initialize (char *argv[])
  426. {
  427.     POINTER    *ptr;
  428.     char    **pp, *p;
  429.     int    gotit;
  430.     int    i;
  431.  
  432.     st.object_id = 1000;            /* reserve 1-999 */
  433.     st.paralax = 12;
  434.     st.focus = VMAX;
  435.     st.gap = 64;
  436.     st.quiet = 1;
  437.     st.gravity = (int) (C_G*VONE);
  438.     st.windows = WIN_FULL;
  439.     st.flags  |= SF_PAUSEMSG;
  440.     st.flags1 |= SF_USEG;
  441.     st.info = 1;
  442.     st.extview = HDT_RADAR;
  443.     st.maxbuffers = 200;
  444.     st.maxrecall = 20;
  445.     st.SkyLines = 50;            /* sky lines */
  446.     st.network |= NET_AUTOACCEPT;
  447.     st.misc[6] = 100;            /* min plane interval */
  448.     st.misc[9] = -1;            /* flush log immediatly */
  449.     st.nMacros = 256;
  450.  
  451. /* initial palette settings
  452. */
  453.     st.palette[CC_BLACK]   = C_BLACK;
  454.     st.palette[CC_RED]     = C_RED;
  455.     st.palette[CC_BLUE]    = C_BLUE;
  456.     st.palette[CC_MAGENTA] = C_MAGENTA;
  457.     st.palette[CC_GREEN]   = C_GREEN;
  458.     st.palette[CC_BROWN]   = C_BROWN;
  459.     st.palette[CC_GRAY]    = C_GRAY;
  460.     st.palette[CC_DYELLOW] = C_DYELLOW;
  461.     st.palette[CC_YELLOW]  = C_YELLOW;
  462.     st.palette[CC_LRED]    = C_LIGHTRED;
  463.     st.palette[CC_LBLUE]   = C_LIGHTBLUE;
  464.     st.palette[CC_LGRAY]   = C_LIGHTGRAY;
  465.     st.palette[CC_SPARE1]  = C_GRAY;
  466.     st.palette[CC_SKYBLUE] = C_SKYBLUE;
  467.     st.palette[CC_DGREEN]  = C_DGREEN;
  468.     st.palette[CC_WHITE]   = C_WHITE;
  469.  
  470. /* default pixel settings
  471. */
  472.     for (i = 0; i < rangeof (st.colors); ++i)
  473.         st.colors[i] = i;
  474.  
  475. /* default colors assignements
  476. */
  477.     ST_INFO   = CC_WHITE;
  478.     ST_MFG    = CC_WHITE;
  479.     ST_WFG    = CC_GREEN;
  480.     ST_CFG    = CC_RED;
  481.     ST_HFG    = CC_DYELLOW;
  482.     ST_HFGI   = CC_YELLOW;
  483.     ST_HBO    = CC_GRAY;
  484.     ST_SLEFT  = CC_RED;
  485.     ST_SRIGHT = CC_BLUE;
  486.     ST_SBOTH  = CC_MAGENTA;
  487.     ST_GROUND = CC_GRAY;
  488.     ST_DULL   = CC_GRAY;
  489.     ST_FAINT  = CC_LGRAY;
  490.     ST_SKY    = CC_SKYBLUE;
  491.     ST_FRIEND = CC_LBLUE;
  492.     ST_FOE    = CC_LRED;
  493.     ST_HELP   = CC_GREEN;
  494.     ST_FIRE1  = CC_WHITE;
  495.     ST_FIRE2  = CC_RED;
  496.     ST_MENU   = CC_LGRAY;
  497.     ST_MENUH  = CC_WHITE;
  498.  
  499.     sim_set ();
  500.  
  501.     Sys = &SysNone;
  502.     Tm = &TmNone;
  503.     Snd = &SndNone;
  504.     Kbd = &KbdNone;
  505.  
  506. /* First we bring up the system and time drivers, these are essential.
  507. */
  508.  
  509.     if (F(Sys = &SysDriver) || Sys->Init ()) {
  510.         Sys = &SysNone;
  511.         LogPrintf ("system mgr init failed\n");
  512.         die ();
  513.     }
  514.  
  515.     if (F(Tm = &TmDriver) || Tm->Init (0)) {
  516.         Tm = &TmNone;
  517.         LogPrintf ("timer mgr init failed\n");
  518.         die ();
  519.     }
  520.     st.big_bang = Tm->Milli ();
  521.  
  522.     if (mem_init ()) {
  523.         LogPrintf ("memory mgr init failed\n");
  524.         die ();
  525.     }
  526.  
  527.     Frandomize ();
  528.  
  529.     for (pp = argv+1; T(p = *pp); ++pp) {
  530.         if ('-' == p[0])
  531.             ++p;
  532.         if ('I' == p[0]) {
  533.             st.iname = STRfree (st.iname);
  534.             st.iname = STRdup (p+1);
  535.         } else if ('F' == p[0]) {
  536.             st.fdir = STRfree (st.fdir);
  537.             st.fdir = STRdup (p+1);
  538.         } else if ('L' == p[0]) {
  539.             if ('\0' != p[1]) {
  540.                 st.lname = xfree (st.lname);
  541.                 st.lname = strdup (p+1);
  542.             }
  543.         }
  544.     }
  545.  
  546.     if (log_init ())
  547.         die ();
  548.  
  549.     if (msg_init ()) {
  550.         LogPrintf ("no messages\n");
  551.         die ();
  552.     }
  553.  
  554.     LogPrintf ("Fly8 start: %s\n", Tm->Ctime ());
  555.     LogPrintf ("Program  %s\n", argv[0]);
  556.     welcome (1);
  557.  
  558.     if (get_iniopts () || get_envopts () || get_argopts (argv+1))
  559.         die ();
  560.  
  561.     if (-1 == st.misc[9])
  562.         st.misc[9] = 1000;        /* flush log on 1sec idle */
  563.  
  564.     if (st.timeropts && Tm->Init (st.timeropts)) {
  565.         Tm = &TmNone;
  566.         LogPrintf ("timer re-init failed\n");
  567.         die ();
  568.     }
  569.     if (!st.nikname)
  570.         st.nikname = STRdup ("JohnDoe");
  571.     if (!st.teamname)
  572.         st.teamname = STRdup ("[*]");
  573.  
  574.     Fsrand ((int)Tm->Milli ());        /* don't be boring */
  575.  
  576.     if (funcs_init ()) {
  577.         LogPrintf ("funcs init failed\n");
  578.         die ();
  579.     }
  580.  
  581.     Kbd = kbrd_init (st.kbdname);
  582.     if (!Kbd || Kbd->Init (st.kbdname)) {
  583.         Kbd = &KbdNone;
  584.         LogPrintf ("keyboard init failed\n");
  585.         die ();
  586.     }
  587.  
  588. /* In the next section 'Snd' is temporarily set to zero. Handle this
  589.  * carefully since many programs use it blindly.
  590. */
  591.     gotit = 0;
  592.     if (F(Snd = sound_init (st.sndname)) || Snd->Init (st.sndname)) {
  593.         Snd = &SndNone;        /* always safe */
  594.         LogPrintf ("sound init failed\n");
  595.     } else
  596.         gotit = 1;
  597.     if (!gotit && st.sndname && (F(Snd = sound_init (0)) || Snd->Init (0))) {
  598.         Snd = &SndNone;        /* always safe */
  599.         LogPrintf ("default sound init failed\n");
  600.     } else
  601.         gotit = 1;
  602.  
  603.     if (!gotit && (F(Snd = sound_init ("")) || Snd->Init (""))) {
  604.         Snd = &SndNone;        /* always safe */
  605.         LogPrintf ("'NoSound' sound init failed\n");
  606.         die ();
  607.     }
  608.     st.sndname = STRfree (st.sndname);
  609.     st.sndname = STRdup (Snd->name);
  610.  
  611.     if (!NEW (CS)) {
  612.         LogPrintf ("out of memory [%s(%u)]\n", __FILE__, __LINE__);
  613.         die ();
  614.     }
  615.  
  616.     if (!NEW (CW)) {
  617.         LogPrintf ("out of memory [%s(%u)]\n", __FILE__, __LINE__);
  618.         die ();
  619.     }
  620.  
  621.     if (!NEW (CP)) {
  622.         LogPrintf ("out of memory [%s(%u)]\n", __FILE__, __LINE__);
  623.         die ();
  624.     }
  625.  
  626.     if (0 == (Gr = devices_init (st.grname))) {
  627.         LogPrintf ("devices init failed\n");
  628.         die ();
  629.     }
  630.  
  631.     CS->device = devices_select (st.grmname);
  632.     if (CS->device == 0 || Gr->Init (CS->device, st.grname)) {
  633.         if (st.grmname) {
  634.             LogPrintf ("no device: %s\n", st.grname);
  635.             LogPrintf ("trying default\n");
  636.             devices_release ();
  637.             CS->device = devices_select (NULL);
  638.         } else
  639.             CS->device = 0;
  640.         if (CS->device == 0 || Gr->Init (CS->device, st.grname)) {
  641.             devices_release ();
  642.             LogPrintf ("no device\n");
  643.             die ();
  644.         }
  645.     }
  646.     if (!Gr->SetVisual || !    Gr->SetActive)
  647.         CS->device->npages = 1;
  648.  
  649. /* Default color assignments.
  650. */
  651.     CS->FgColor = CC_WHITE;
  652.     CS->BgColor = CC_BLACK;
  653.     CS->BoColor = CC_LGRAY;
  654.  
  655.     for (i = 0; i < rangeof (st.hdd); ++i) {
  656.         st.hdd[i].FgColor = CC_WHITE;
  657.         st.hdd[i].BgColor = CC_BLACK;
  658.         st.hdd[i].BoColor = CC_LGRAY;
  659.     }
  660.  
  661.     set_palette ();
  662.     set_main ();
  663.  
  664. /* Now we are in graphics mode!
  665. */
  666.     st.grmname = STRfree (st.grmname);
  667.     st.grmname = STRdup (CS->device->name);
  668.  
  669.     font_set (0);
  670.     st.StFontSize = 8;
  671.  
  672.     if (mac_init ()) {
  673.         LogPrintf ("no macros");
  674.         die ();
  675.     }
  676.  
  677.     MsgPrintf (-100, "System   %s", Sys->name);
  678.     MsgPrintf (-100, "Timer    %s", Tm->name);
  679.     MsgPrintf (-100, "Graphics %s", Gr->name);
  680.     MsgPrintf (-100, " vmodes  %s", st.vmdname);
  681.     MsgPrintf (-100, " mode    %s", st.grmname);
  682.     MsgPrintf (-100, "Sound    %s", Snd->name);
  683.     MsgPrintf (-100, "Keyboard %s", Kbd->name);
  684.  
  685.     MsgPrintf (-100, "nBuffers %u", st.maxbuffers);
  686.  
  687.     if (edit_init ()) {
  688.         LogPrintf ("no edit_str\n");
  689.         die ();
  690.     }
  691.  
  692.     if (pointers_init ()) {
  693.         LogPrintf ("no pointers\n");
  694.         die ();
  695.     }
  696.  
  697.     if (bodies_init ()) {
  698.         LogPrintf ("no bodies\n");
  699.         die ();
  700.     }
  701.  
  702.     if (land_init ()) {
  703.         LogPrintf ("no land\n");
  704.         die ();
  705.     }
  706.  
  707.     if (nav_init ()) {
  708.         LogPrintf ("no nav\n");
  709.         die ();
  710.     }
  711.     if ((st.home = nav_find (st.homename)) < 0) {
  712.         LogPrintf ("bad home name \"%s\"\n", st.homename);
  713.         st.home = 0;
  714.     }
  715.  
  716. /* We are initialized, now get us a plane. First find the pointer.
  717. */
  718.     if (F(ptr = pointer_select (st.ptrname))) {
  719.         if (st.ptrname) {
  720.             MsgEPrintf (-100, "no ptr: %s", st.ptrname);
  721.             st.ptrname = STRfree (st.ptrname);
  722.         }
  723.         MsgPrintf (-100, "trying default");
  724.         if (F(ptr = pointer_select (NULL))) {
  725.             LogPrintf ("no pointer\n");
  726.             die ();
  727.         }
  728.         st.ptrname = STRdup (ptr->name);
  729.     }
  730.     MsgPrintf (-100, "Pointer  %s", ptr->name);
  731.  
  732.     CO = COT = 0;
  733.  
  734.     st.options = st.ptype;
  735.     if (!(CC = create_object (O_PLANE, 1))) {
  736.         LogPrintf ("no plane %s\n", st.ptype);
  737.         pointer_release (ptr);
  738.         die ();
  739.     }
  740.     CC->pointer = ptr;
  741.     ptr->l[9] = 100;        /* brakes */
  742.     CC->flags |= F_CC | F_FRIEND;
  743.     CC->color = CC_LBLUE;
  744.     CC->gpflags |= GPF_PILOT;
  745.     place_plane (CC, st.home);
  746.     CV = CC;
  747.  
  748. /* Establish the virtual viewers.
  749. */
  750.     create_viewer (HDT_FRONT, 0);
  751.     create_viewer (HDT_REAR, 0);
  752.     create_viewer (HDT_MAP, 0);
  753.     create_viewer (HDT_RADAR, 0);
  754.     create_viewer (HDT_TARGET, 12);
  755.     create_viewer (HDT_PAN, 12);
  756.     create_viewer (HDT_GAZE, 0);
  757.     create_viewer (HDT_CHASE, 0);
  758.     create_viewer (HDT_FOLLOW, 0);
  759.  
  760.     create_viewer (HDT_RIGHT, 0);
  761.     create_viewer (HDT_LEFT,  0);
  762.  
  763.     create_viewer (HDT_MIRROR, -3);        /* somewhat wide angle */
  764.  
  765. /* Now get the net going.
  766. */
  767.     remote_init ();
  768.  
  769. /* We made it, tell the world.
  770. */
  771.     welcome (0);            /* welcome everybody */
  772.     if (st.quiet) {
  773.         Snd->Effect (EFF_HELLO, SND_ON);
  774.         if (st.quiet >= 2)
  775.             Snd->Effect (EFF_ENGINE, SND_ON);
  776.     }
  777.  
  778.     cc_setup ();
  779.  
  780.     double_buffer (SF_DBUFFERING);
  781.  
  782.     st.flags |= SF_INITED;
  783.     if (Gr->Shutters)
  784.         Gr->Shutters (-1);        /* turn on */
  785.  
  786.     st.DroneTime = st.present;
  787.  
  788.     {
  789.         static Ushort    keys[] = {KF_INIT};    /* startup macro */
  790.         Ushort        key, shift;
  791.         int        i;
  792.  
  793.         if (NULL == st.initkeys)
  794.             mac_interpret (keys, rangeof (keys));
  795.         else {
  796.             shift = K_CTRL;
  797.             for (i = 0; T(key = st.initkeys[i]); ++i) {
  798.                 if ('C' == key)
  799.                     shift = K_CTRL;
  800.                 else if ('A' == key)
  801.                     shift = K_ALT;
  802.                 else if (isalpha (key)) {
  803.                     keys[0] = shift + tolower (key);
  804.                     mac_interpret (keys, rangeof (keys));
  805.                 } else {
  806.                     MsgEPrintf (-100, "bad initkeys");
  807.                     break;
  808.                 }
  809.             }
  810.         }
  811.     }
  812.  
  813.     log_flush (1);
  814.  
  815.     sim_reset ();
  816. }
  817.